#include <stdio.h>
#include "dispatcher.h"

/*Dispatcher::Dispatcher(){
	//corres.setPort(9877);	
}

Dispatcher::~Dispatcher(){
}*/

int Dispatcher::mapToFile(char* filename, int s_level) {
	FILE* fp;
	map<string,vector<source_node> >:: iterator iter_map;
	vector<source_node>:: iterator iter_vec;

	if((fp = fopen(filename,"w")) < 0){
		printf("open file error\n");
		return 0;
	}
	fprintf(fp, "%d ", s_level);
	for(iter_map = index.begin();iter_map != index.end();iter_map++){
		fprintf(fp,"%s ",(iter_map->first).c_str());		// source name;
		fprintf(fp,"%d ",(iter_map->second).size());
		for(iter_vec = (iter_map->second).begin();iter_vec != (iter_map->second).end();iter_vec++){
			fprintf(fp,"%s ",(*iter_vec).ip.c_str());
		}
	}

	fclose(fp);
	return 1;
}

int Dispatcher::fileToMap(char* filename){
	FILE* fp;
	char name[50];
	int num;
	int i;
	char tmp[20];
	int flag = 0;
	int ln;
	source_node sn;
//	string s;
	vector<source_node>:: iterator iter_vec;
	
	if((fp = fopen(filename,"r")) < 0){
                printf("open file error\n");
                return 0;
        }
	fscanf(fp, "%d", &i);
	//fflush(fp);
	while(!feof(fp)){
		fscanf(fp,"%s",name);
		fscanf(fp,"%d",&num); 
		for(i=0;i<num;i++){
			fscanf(fp,"%s",tmp);
			for(iter_vec = index[name].begin();iter_vec != index[name].end();iter_vec++){
				if(!strcmp((*iter_vec).ip.c_str(),tmp)){
					flag = 1;
					break;
				}
			}
			if(flag == 1)
				flag = 0;
			else{
				sn.ip = tmp;
				index[name].push_back(sn);
			}
		}
	}
	fclose(fp);
	return 1;
}

int Dispatcher::convert_ip_info(char* szIP, ip_info* pInfo){

	int nLen = strlen(szIP);
        int i;
        int nCurrent;
        int j = 0;
        nCurrent =0;
        for(i=0;i<nLen+1;i++){
                if((szIP[i] == '.')||(szIP[i] == 0))
                {
                        if(nCurrent >= 256)
                                return 0; //error
                        pInfo->ip[j] = nCurrent;
                        nCurrent = 0;
                        j++;
                        if(j==5)
                                break;
                }
                else
                {
                        if((szIP[i] >='0')&&(szIP[i] <='9')){
                                nCurrent = nCurrent * 10 + (szIP[i] - '0');
                        }
                        else
                        {
                                return 0;
                        }
                }
       }
       pInfo->mask = 0;
       return 1;
}

int Dispatcher::convert_seg_info(const char* szIP, ip_info* pInfo)
{
        int nLen = strlen(szIP);
        int i,nTimes;
        int nCurrent;
        int j = 0;
        nCurrent =0;
        for(i=0;i<nLen;i++)
        {
                if((szIP[i] == '.')||(szIP[i] == '/'))
                {
                        if(nCurrent >= 256)
                                return 0; //error
                        pInfo->ip[j] = nCurrent;
                        nCurrent = 0;
                        j++;
                        if(j==4)
                                break;
                }
                else
                {
                        if((szIP[i] >='0')&&(szIP[i] <='9'))
                        {
                                nCurrent = nCurrent * 10 + (szIP[i] - '0');
                        }
                        else
                        {
                                return 0;
                        }
                }
        }
        if((j!=4)||(i==nLen))
                return 0;
        nCurrent =0;
        for(j=i+1;j<nLen;j++)
        {

                if((szIP[j] >'9')||(szIP[j]<'0'))
                        return 0;
                nCurrent = nCurrent * 10 + (szIP[j] - '0');
        }
        pInfo->mask = nCurrent;
        return 1;
}

int Dispatcher::is_ip_in_seg(const ip_info *pIP, const ip_info* pSeg)
{
        int mask = pSeg->mask;
        int i;
        int ip,seg;
        i=0;
        if(mask >= 32)
                return 0;

        while(mask>=8){
                mask -= 8;
                if(pIP->ip[i] != pSeg->ip[i])
                        return 0;
                i++;
        }

        if(mask == 0)
                return 1;

        ip = pIP->ip[i];
        seg = pSeg->ip[i];

        ip = ip >> (8 - mask);
        seg = seg >> (8 - mask);
        if(ip == seg)
                return 1;
        else
                return 0;
}

int Dispatcher::match_ip(const char *seg,char *ip)
{
    int nRet;
    ip_info ipInfo, segInfo;
    convert_seg_info(seg,&segInfo);
    convert_ip_info(ip, &ipInfo);
    nRet = is_ip_in_seg(&ipInfo,&segInfo);
    return nRet;
}

int Dispatcher::has_source(char* filename){
	vector<source_node>::iterator iter;

	if(index[filename].size() > 0){
		for(iter = index[filename].begin();iter != index[filename].end();iter++){
			if(loadmap[(*iter).ip] <= MAXLOAD)
				return 1;
		}
		return 0;	
	}
	else 
		return 0;
}

int Dispatcher::findFit(char* filename,char ip[]){
	vector<source_node>::iterator iter_vec;
	int min;

	if(index[filename].size() <= 0)
		return 0;
	iter_vec = index[filename].begin();
	min = loadmap[(*iter_vec).ip];
	strcpy(ip,(*iter_vec).ip.c_str());
	iter_vec++;
	while(iter_vec != index[filename].end()){
		if(loadmap[(*iter_vec).ip] < min){
			strcpy(ip,(*iter_vec).ip.c_str());
			min = loadmap[(*iter_vec).ip];
		}
		iter_vec++;
	}
	return 1;	
}

void Dispatcher::initRS()
{
    index.clear();
    loadmap.clear();
}

void Dispatcher::mapToStr(char str[]){
	map<string,int>::iterator iter;
	char tmp[30];
	char* ptr = str;

	for(iter = loadmap.begin();iter != loadmap.end();iter++){
			sprintf(tmp,"%s %d %c",(iter->first).c_str(),iter->second,'\0');
			sprintf(ptr,"%s",tmp);
			ptr = ptr + strlen(tmp);
	}

	*ptr = '\0';
}

void Dispatcher::strToMap(char str[]){
	map<string,int>::iterator iter;
	int i,load;
	char tmp[30];
	char* ptr = str;
        while(*ptr != '\0'){
		i = 0;
                while((*ptr!= '\0')&&((*ptr) != ' ')){
                        tmp[i] = *ptr;
                        ptr++;
                        i++;
                }
                tmp[i] = '\0';
                if(*ptr != '\0')
                        ptr++;
                string s = tmp;

                i = 0;
                while((*ptr != '\0')&&((*ptr) != ' ')){
                        tmp[i] = *ptr;
                        ptr++;
                        i++;
                }

                        tmp[i] = '\0';
                if(*ptr != '\0')
                        ptr++;
                        i++;

                load = atoi(tmp);
                loadmap[s] = load;
        }
}

void Dispatcher::addIndex(char* ip,char* filename){
	source_node sn;
        sn.ip = ip;
       	index[filename].push_back(sn);
}

void Dispatcher::deleteIndex(char* ip,char* filename){
	vector<source_node>::iterator iter;
	for(iter = index[filename].begin();iter != index[filename].end();iter++){
		if(!strcmp((*iter).ip.c_str(),ip))
			break;
	}
	if(iter != index[filename].end())
        	index[filename].erase(iter);
        if(index[filename].size() == 0)
		index.erase(filename);
}

int Dispatcher::deleteNode(string ip){
	map<string,vector<source_node> >::iterator iter_map;
	vector<source_node>::iterator iter_vec;
	
	for(iter_map = index.begin();iter_map != index.end();iter_map++){
		for(iter_vec = (iter_map->second).begin(); iter_vec !=(iter_map->second).end(); iter_vec++)
				if(iter_vec->ip == ip){
					(iter_map->second).erase(iter_vec);
					break;
				}
	}
	loadmap.erase(ip);
}

/*
int main(){
	Dispatcher d;
	map<string,vector<source_node> >:: iterator iter_map;
        vector<source_node>:: iterator iter_vec;
	source_node sn;
//	char s[20];
	map<string,int>::iterator iter;
	d.loadmap["59.77.17.136"] = 34;
	d.loadmap["135.34.45.33"] = 124;
	d.loadmap["210.34.0.17"] = 317;

	for(iter = d.loadmap.begin();iter!= d.loadmap.end();iter++)
		printf("%s -> %d\n",(iter->first).c_str(),iter->second);

	char s[] =  "133.234.3.55 34 59.77.17.3113 3435 359.32.119.33 563 133.234.3.55 2334 111.34.454.54 13 59.77.17.3113 23";
	d.strToMap(s);

	printf(">>>>>>>>>>>>>>>>>>>> After Reading <<<<<<<<<<<<<<<<<<<<<<<\n");
	for(iter = d.loadmap.begin();iter!= d.loadmap.end();iter++)
                printf("%s -> %d\n",(iter->first).c_str(),iter->second);

	char str[4096];
	d.mapToStr(str);
	printf("str = %s\n",str);
*/
/*	
	sn.ip = "59.77.16.78";
//	sn.linknum = 31;
	d.index["000.mov"].push_back(sn);

        sn.ip = "59.77.16.88";
//        sn.linknum = 23;
	d.index["001.mov"].push_back(sn);

        sn.ip = "59.77.16.78";
  //      sn.linknum = 43;
	d.index["002.mov"].push_back(sn);

        sn.ip = "59.77.16.178";
    //    sn.linknum = 29;	
	d.index["003.mov"].push_back(sn);

        sn.ip = "59.77.16.99";
      //  sn.linknum = 57;
	d.index["000.mov"].push_back(sn);

        for(iter_map = d.index.begin();iter_map != d.index.end();iter_map++){
                printf("filename :%s \n",(iter_map->first).c_str());            // source name;
     //           fprintf(fp,"%d ",(iter_map->second).size());
                for(iter_vec = (iter_map->second).begin();iter_vec != (iter_map->second).end();iter_vec++){
                        printf("ip :%s \n",(*iter_vec).ip.c_str());
                }
		printf("\n");
		printf("=====================\n");
        }
	d.fileToMap("source.txt");
	printf(">>>>>>>>>> after reading <<<<<<<<<<\n");
	for(iter_map = d.index.begin();iter_map != d.index.end();iter_map++){
                printf("%s :\n",(iter_map->first).c_str());            // source name;
     //           fprintf(fp,"%d ",(iter_map->second).size());
                for(iter_vec = (iter_map->second).begin();iter_vec != (iter_map->second).end();iter_vec++){
                        printf("%s \n",(*iter_vec).ip.c_str());
                }
                printf("\n");
                printf("=====================\n");
        }

	d.mapToFile("source.txt");
*/
/*	char ip[20];
	char ip_seg[30];
	printf("enter ip seg:\n");
	scanf("%s",ip_seg);
	printf("enter ip:\n");
	scanf("%s",ip);
	if(d.match_ip(ip_seg,ip))
		printf("match!\n");
	else
		printf("un_match!\n");
*/
/*	if(d.has_source("010.mov"))
		printf("has it\n");
	else 
		printf("don't has it\n");

	if(d.findFit("000.mov",s))
		printf("ip = %s\n",s);		

	return 0;
}
*/
/*	return 0;
}*/					
